/*
 * camera_udp.c
 *
 *  Created on: Feb 16, 2023
 *      Author: Administrator
 */

#include "camera_udp.h"
#include "wchnet.h"
#include "eth_driver.h"
#include "net_config.h"
#include "debug.h"

u8 MACAddr[6];                                   //MAC address
u8 IPAddr[4] = { 192, 168, 4, 250 };              //IP address
u8 GWIPAddr[4] = { 192, 168, 4, 254 };             //Gateway IP address
u8 IPMask[4] = { 255, 255, 255, 0 };             //subnet mask
u16 srcport = 1000;                              //source port

u8 SocketId;
u8 SocketRecvBuf[RECE_BUF_LEN];                  //socket receive buffer

/*********************************************************************
 * @fn      mStopIfError
 *
 * @brief   check if error.
 *
 * @param   iError - error constants.
 *
 * @return  none
 */
void mStopIfError(u8 iError)
{
    if (iError == WCHNET_ERR_SUCCESS)
        return;
    printf("Error: %02X\r\n", (u16) iError);
}

/*********************************************************************
 * @fn      WCHNET_UdpServerRecv
 *
 * @brief   UDP Receive data function
 *
 *@param    socinf - socket information.
 *          ipaddr - The IP address from which the data was sent
 *          port - source port
 *          buf - pointer to the data buffer
 *          len - received data length
 * @return  none
 */
void WCHNET_UdpServerRecv(struct _SCOK_INF *socinf, u32 ipaddr, u16 port, u8 *buf, u32 len)
{
    u8 ip_addr[4], i;

    printf("Remote IP:");
    for (i = 0; i < 4; i++) {
        ip_addr[i] = ipaddr & 0xff;
        printf("%d ", ip_addr[i]);
        ipaddr = ipaddr >> 8;
    }

    printf("srcport = %d len = %d socketid = %d\r\n", port, len,
            socinf->SockIndex);

    WCHNET_SocketUdpSendTo(socinf->SockIndex, buf, &len, ip_addr, port);
}

/*********************************************************************
 * @fn      WCHNET_CreateUdpSocket
 *
 * @brief   Create UDP Socket
 *
 * @return  none
 */
void WCHNET_CreateUdpSocket(void)
{
    u8 i;
    SOCK_INF TmpSocketInf;

    memset((void *) &TmpSocketInf, 0, sizeof(SOCK_INF));
    TmpSocketInf.SourPort = srcport;
    TmpSocketInf.ProtoType = PROTO_TYPE_UDP;
    TmpSocketInf.RecvStartPoint = (u32) SocketRecvBuf;
    TmpSocketInf.RecvBufLen = RECE_BUF_LEN;
    TmpSocketInf.AppCallBack = WCHNET_UdpServerRecv;
    i = WCHNET_SocketCreat(&SocketId, &TmpSocketInf);
    printf("WCHNET_SocketCreat %d\r\n", SocketId);
    mStopIfError(i);
}

/*********************************************************************
 * @fn      WCHNET_HandleSockInt
 *
 * @brief   Socket Interrupt Handle
 *
 * @param   socketid - socket id.
 *          intstat - interrupt status
 *
 * @return  none
 */
void WCHNET_HandleSockInt(u8 socketid, u8 intstat)
{
    if (intstat & SINT_STAT_RECV)                               //receive data
    {
    }
    if (intstat & SINT_STAT_CONNECT)                            //connect successfully
    {
        printf("TCP Connect Success\r\n");
    }
    if (intstat & SINT_STAT_DISCONNECT)                         //disconnect
    {
        printf("TCP Disconnect\r\n");
    }
    if (intstat & SINT_STAT_TIM_OUT)                            //timeout disconnect
    {
        printf("TCP Timeout\r\n");
    }
}

/*********************************************************************
 * @fn      WCHNET_HandleGlobalInt
 *
 * @brief   Global Interrupt Handle
 *
 * @return  none
 */
void WCHNET_HandleGlobalInt(void)
{
    u8 intstat;
    u16 i;
    u8 socketint;

    intstat = WCHNET_GetGlobalInt();                              //get global interrupt flag
    if (intstat & GINT_STAT_UNREACH)                              //Unreachable interrupt
    {
        printf("GINT_STAT_UNREACH\r\n");
    }
    if (intstat & GINT_STAT_IP_CONFLI)                            //IP conflict
    {
        printf("GINT_STAT_IP_CONFLI\r\n");
    }
    if (intstat & GINT_STAT_PHY_CHANGE)                           //PHY status change
    {
        i = WCHNET_GetPHYStatus();
        if (i & PHY_Linked_Status)
            printf("PHY Link Success\r\n");
    }
    if (intstat & GINT_STAT_SOCKET) {                             //socket related interrupt
        for (i = 0; i < WCHNET_MAX_SOCKET_NUM; i++) {
            socketint = WCHNET_GetSocketInt(i);
            if (socketint)
                WCHNET_HandleSockInt(i, socketint);
        }
    }
}


void camera_udp_init()
{
	u8 i;

	printf("UdpServer Test\r\n");
	printf("SystemClk:%d\r\n", SystemCoreClock);
	printf("net version:%x\n", WCHNET_GetVer());
	if ( WCHNET_LIB_VER != WCHNET_GetVer()) {
		printf("version error.\n");
	}
	WCHNET_GetMacAddr(MACAddr);                                   //get the chip MAC address
	printf("mac addr:");
	for(i = 0; i < 6; i++)
		printf("%x ",MACAddr[i]);
	printf("\n");
	//TIM2_Init();
	i = ETH_LibInit(IPAddr, GWIPAddr, IPMask, MACAddr);           //Ethernet library initialize
	mStopIfError(i);
	if (i == WCHNET_ERR_SUCCESS)
		printf("WCHNET_LibInit Success\r\n");
	WCHNET_CreateUdpSocket();                                     //Create  UDP Socket

}

void camera_udp_task()
{
	/*Ethernet library main task function,
	 * which needs to be called cyclically*/
	WCHNET_MainTask();
	/*Query the Ethernet global interrupt,
	 * if there is an interrupt, call the global interrupt handler*/
	if(WCHNET_QueryGlobalInt())
	{
		WCHNET_HandleGlobalInt();
	}
}

void camera_udp_send_data(u8 *udp_data, uint32_t udp_len)
{
	u8 ip_addr[4] = {192,168,4,255};
	u8 i;

//	printf("UDP Send:%d", udp_len);
//	printf("Remote IP:");
//	for (i = 0; i < 4; i++) {
//		printf("%d ", ip_addr[i]);
//	}

	//printf("srcport = %d len = %d socketid = %d\r\n", srcport, udp_len, 0);

	WCHNET_SocketUdpSendTo(0, udp_data, &udp_len, ip_addr, srcport);
}
